<?php
// +----------------------------------------------------------------------
// | Copyright (c) 2019~2022 https://www.meoyun.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件，不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 喵云科技 【https://www.meoyun.com】
// +----------------------------------------------------------------------


namespace app\api\controller;

use app\common\service\WeChatMnpService;
use app\model\FollowModel;
use app\model\PostModel;
use app\model\TopicAdminModel;
use app\model\TopicModel;
use app\model\UsersModel;
use app\model\TopicClassModel;
use app\model\UserTopicModel;

class Topic extends BaseApi
{
    protected ?string $dataModel = TopicModel::class;
    protected array $allowSearch = ['name', 'description', 'status', 'creator_id', 'class_id'];

    public function list()
    {
        $classId = input("class_id");
        $keyword = input("keyword");

        $where[] = ['status', '=', 2];
        if ($classId) {
            $where[] = ["class_id", "=", $classId];
        }

        if ($keyword) {
            $where[] = ["name", "like", "%" . $keyword . "%"];
        }

        $list = TopicModel::where($where)->paginate(10);

        return $this->dataByPage($list);
    }

    //分类列表
    public function classList()
    {
        $list = TopicClassModel::get();
        return $this->success($list);
    }

    //热门圈子
    public function hot()
    {
        $count = input('count', 10);
        $list = TopicModel::with(['user'])->orderBy('post_num', 'desc')->limit($count)->get();
        return $this->success($list);
    }

    public function postClassList()
    {
        $topicId = input("topic_id");
        $list = TopicClassModel::where('topic_id', $topicId)->get()->toArray();
        return $this->success($list);
    }

    //当前登录用户加入的圈子列表
    public function currentUserJoinTopic()
    {
        $userId = $this->getUserId();

        $topicIds = UserTopicModel::where('user_id', $userId)->orderBy('updated_at', 'desc')->pluck('topic_id')->toArray();

        $list = TopicModel::whereIn('id', $topicIds)->get();

        return $this->success($list);
    }

    //圈子详情
    public function detail()
    {
        $id = input("id");
        $userId = $this->getUserId();
        $topic = TopicModel::with(['user'])->whereIn('status', [1, 2])->find($id);

        if (!$topic) {
            return $this->fail('圈子不存在或已关闭', 0);
        }

        $userIds = \app\model\UserTopicModel::where('topic_id', $id)->pluck('user_id')->toArray();

        $adminUid = \app\model\TopicAdminModel::where('topic_id', $id)->pluck('user_id')->toArray();
        $topic['admin_list'] = UsersModel::orderBy('updated_at', 'desc')->whereIn('id', $adminUid)->limit(9)->get()->each(function ($item) use ($userId) {
            $item['is_follow'] = \app\model\FollowModel::where('user_id', $userId)->where('follow_user_id', $item['id'])->exists();
            return $item;
        });

        //置顶帖子
        $postIds = \app\model\TopicTopModel::where('topic_id', $id)->pluck('post_id')->toArray();
        $topic["top_post"] = \app\model\PostModel::whereIn('id', $postIds)->get();

        $topic['user_num'] = \app\model\UserTopicModel::where('topic_id', $id)->count();
        $topic['post_num'] = \app\model\PostModel::where('topic_id', $id)->count();

        if ($userId) {
            $topic['is_join'] = \app\model\UserTopicModel::where('user_id', $userId)->where('topic_id', $id)->exists();
            $topic['is_admin'] = in_array($userId, $adminUid);
        }

        return $this->success($topic->toArray());
    }

    //查询圈子内用户列表
    public function userList()
    {
        $id = input("id");
        $userId = $this->getUserId();

        $topicUid = TopicModel::where('id', $id)->value('user_id');
        $userIds = UserTopicModel::where('topic_id', $id)->pluck('user_id')->toArray();
        $paginate = UsersModel::orderBy('updated_at', 'desc')->where("id", "<>", $topicUid)->whereIn("id", $userIds)->paginate(10);

        $list = $paginate->items();

        foreach ($list as $item) {
            $item['is_follow'] = FollowModel::where('user_id', $userId)->where('follow_uid', $item['id'])->exists();

            $item['is_admin'] = TopicAdminModel::where(['topic_id' => $id, 'user_id' => $item['id']])->exists() ? 1 : 0;
        }

        return $this->dataByPage($paginate);
    }

    //当前用户创建的圈子
    public function createTopicList()
    {
        $userId = $this->getUserId();

        $list = TopicModel::where('user_id', $userId)->paginate(10)->toArray();

        return $this->dataByPage($list);
    }

    //搜索
    public function search()
    {
        $keyword = input("keyword");
        $where[] = ["name", "like", "%$keyword%"];
        $paginate = TopicModel::where($where)->paginate(10);
        return $this->dataByPage($paginate);
    }

    //创建圈子

    /**
     * 创建圈子
     * @return \support\Response
     */
    public function topicAdd()
    {
        try {
            $userId = $this->getUserId();

            // 参数验证
            $params = request()->all();
            $rules = [
                'name' => 'required|string|max:50',
                'description' => 'required|string|max:200',
            ];
            $messages = [
                'name.required' => '圈子名称不能为空',
                'name.max' => '圈子名称不能超过50个字符',
                'description.required' => '圈子介绍不能为空',
                'description.max' => '圈子介绍不能超过200个字符'
            ];

            $validator = validator($params, $rules, $messages);
            if ($validator->fails()) {
                return $this->fail($validator->errors()->first());
            }

            // 检查圈子名称是否已存在
            $existingTopic = TopicModel::where('name', $params['name'])->first();
            if ($existingTopic) {
                return $this->fail('圈子名称已存在，请更换其他名称');
            }

            $params['user_id'] = $userId;
            $params['notice'] = $this->getDefaultNotice();

            // 创建圈子
            $topic = TopicModel::create($params);

            // 创建用户圈子关联
            UserTopicModel::create([
                'user_id' => $userId,
                'topic_id' => $topic->id
            ]);

            return $this->success($topic);

        } catch (\Exception $e) {
            return $this->fail('创建失败：' . $e->getMessage());
        }
    }

    /**
     * 获取圈子默认公告内容
     * @return string
     */
    private function getDefaultNotice(): string
    {
        return '圈子规则：' . PHP_EOL .
            '1、不得发布违法、涉黄、辱骂内容' . PHP_EOL .
            '2、禁止发布广告，兼职和实习帖子' . PHP_EOL .
            '3、文明发言，文明上网';
    }

    /**
     * 生成圈子二维码
     * @return \support\Response
     */
    public function qrCode()
    {
        try {
            // 参数验证
            $params = request()->all();
            $rules = [
                'topic_id' => 'required|integer|exists:topic,id'
            ];
            $messages = [
                'topic_id.required' => '圈子ID不能为空',
                'topic_id.integer' => '圈子ID必须是整数',
                'topic_id.exists' => '圈子不存在'
            ];
            
            $validator = validator($params, $rules, $messages);
            if ($validator->fails()) {
                return $this->fail($validator->errors()->first());
            }
            
            $topicId = $params['topic_id'];
            
            // 检查圈子是否存在且状态正常
            $topic = TopicModel::where('id', $topicId)
                ->where('status', 1)
                ->first();
            if (!$topic) {
                return $this->fail('圈子不存在或已被禁用');
            }
            
            // 检查二维码是否已存在
            $qrcodePath = public_path() . 'qrcode' . DIRECTORY_SEPARATOR . 'topic';
            $filename = $qrcodePath . DIRECTORY_SEPARATOR . $topicId . '.png';
            
            // 如果二维码已存在且文件有效，直接返回
            if (file_exists($filename) && filesize($filename) > 0) {
                $data = [
                    'url' => request()->domain() . "/qrcode/topic/{$topicId}.png",
                    'cached' => true
                ];
                return $this->success('获取成功', $data);
            }
            
            // 创建目录（递归创建）
            if (!is_dir($qrcodePath)) {
                if (!mkdir($qrcodePath, 0755, true)) {
                    return $this->fail('创建二维码目录失败');
                }
            }
            
            // 生成二维码
            $weChatService = new WeChatMnpService();
            $response = $weChatService->getQrCode('pages/index/index', $topicId);
            
            if (!$response) {
                return $this->fail('生成二维码失败');
            }
            
            // 保存二维码文件
            if (!$response->saveAs($filename)) {
                return $this->fail('保存二维码文件失败');
            }
            
            // 验证文件是否保存成功
            if (!file_exists($filename) || filesize($filename) === 0) {
                return $this->fail('二维码文件保存失败');
            }
            
            $data = [
                'url' => request()->domain() . "/qrcode/topic/{$topicId}.png",
                'cached' => false
            ];
            
            return $this->success('生成成功', $data);
            
        } catch (\Exception $e) {
            // 记录错误日志
            \support\Log::error('生成圈子二维码失败', [
                'topic_id' => $params['topic_id'] ?? null,
                'error' => $e->getMessage(),
                'trace' => $e->getTraceAsString()
            ]);
            
            return $this->fail('生成二维码失败：' . $e->getMessage());
        }
    }

    //加入圈子
    public function joinTopic()
    {
        $userId = $this->getUserId();
        $topicId = input("id");

        $isJoin = UserTopicModel::where(['user_id' => $userId, 'topic_id' => $topicId])->exists();

        if ($isJoin) {
            return $this->fail('您已加入该圈子', 0);
        }

        UserTopicModel::create([
            'user_id' => $userId,
            'topic_id' => $topicId
        ]);

        TopicModel::where('id', $topicId)->increment('user_num');
        return $this->success("加入成功");

    }

    //保存圈子板块分类
    public function saveClass()
    {
        $classList = input("class_list");

        foreach ($classList as $item) {
            TopicClassModel::updateOrCreate(
                ['name' => $item['name'], 'topic_id' => $item['topic_id']],
                $item
            );
        }

        return $this->success("保存成功");
    }

    //删除圈子板块分类
    public function classDel()
    {
        $classId = input("id");

        $res = TopicClassModel::where("id", $classId)->delete();

        if ($res) {
            return $this->success("删除成功");
        }

        return $this->fail('删除失败');
    }

    /**
     * 设置圈子信息
     * @return \support\Response
     */
    public function setInfo()
    {
        try {
            $userId = $this->getUserId();
            
            // 参数验证
            $params = request()->all();
            $rules = [
                'topic_id' => 'required|integer|exists:topic,id',
                'field' => 'required|string|in:name,description,cover_image,bg_image,notice',
                'value' => 'nullable|string'
            ];
            $messages = [
                'topic_id.required' => '圈子ID不能为空',
                'topic_id.exists' => '圈子不存在',
                'field.required' => '字段名不能为空',
                'field.in' => '不允许修改该字段',
                'value.string' => '字段值必须是字符串'
            ];
            
            $validator = validator($params, $rules, $messages);
            if ($validator->fails()) {
                return $this->fail($validator->errors()->first());
            }
            
            // 检查圈子是否存在并获取圈子信息
            $topic = TopicModel::find($params['topic_id']);
            if (!$topic) {
                return $this->fail('圈子不存在');
            }
            
            // 权限检查：只有圈子创建者可以修改
            if ($topic->user_id != $userId) {
                return $this->fail('无权限修改该圈子信息');
            }
            
            // 特殊字段验证
            if ($params['field'] === 'name') {
                if (empty($params['value'])) {
                    return $this->fail('圈子名称不能为空');
                }
                if (mb_strlen($params['value']) > 50) {
                    return $this->fail('圈子名称不能超过50个字符');
                }
                // 检查名称是否重复
                $existingTopic = TopicModel::where('name', $params['value'])
                    ->where('id', '!=', $params['topic_id'])
                    ->first();
                if ($existingTopic) {
                    return $this->fail('圈子名称已存在，请更换其他名称');
                }
            }
            
            if ($params['field'] === 'description') {
                if (mb_strlen($params['value']) > 200) {
                    return $this->fail('圈子描述不能超过200个字符');
                }
            }
            
            // 更新圈子信息
            $topic->update([
                $params['field'] => $params['value']
            ]);
            
            return $this->success('编辑成功');
            
        } catch (\Exception $e) {
            return $this->fail('编辑失败：' . $e->getMessage());
        }
    }

    //退出圈子
    public function userQuit()
    {

        $topicId = input("id");
        $userId = $this->getUserId();

        $userTopic = \app\model\UserTopicModel::where(['user_id' => $userId, 'topic_id' => $topicId])->first();

        if (!$userTopic) {
            return $this->fail('您未加入圈子');
        }

        $topicAdminUid = TopicModel::find($topicId)["user_id"];

        if ($topicAdminUid == $userId) {
            return $this->fail("圈主不可退出圈子");
        }

        $userTopic->delete();
        TopicModel::where('id', $topicId)->decrement('user_num');
        return $this->success('退出成功');
    }

    /**
     * 圈子编辑资料
     */
    public function saveInfo()
    {
        $params = request()->all();

        $topic = TopicModel::where("id", $params["id"])->first();

        if (!$topic) {
            return $this->fail("圈子信息错误");
        }

        $topic->name = $params['name'];
        $topic->description = $params['description'];
        $topic->cover_image = $params['cover_image'];
        $topic->bg_image = $params['bg_image'];

        $topic->save();

        return $this->success();
    }

    public function updateOpenTime()
    {
        $userId = $this->getUserId();
        $topic_id = input("topic_id");

        UserTopicModel::where(["user_id" => $userId, "topic_id" => $topic_id])->update([
            "updated_at" => date('Y-m-d H:i:s')
        ]);

        return $this->success();
    }
}